﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;

namespace FrameWork.Core.GroundWork
{
    public class WorkEngine
    {
        private int key;

        private List<WorkParam> list = new List<WorkParam>();

        private BackgroundWorker bgw = new BackgroundWorker();

        private bool running;
        public int Add(WorkParam Param)
        {
            Param.ID = this.key++;
            Param.LastExecuteDateTime = DateTime.Now.AddDays(-1.0);
            lock (this.list)
            {
                this.list.Add(Param);
            }
            return this.key;
        }

        public int Remove(WorkParam Param)
        {
            int result = 0;
            lock (this.list)
            {
                foreach (WorkParam current in this.list)
                {
                    if (current.ID == Param.ID)
                    {
                        this.list.Remove(current);
                        result = 1;
                        break;
                    }
                }
            }
            return result;
        }

        public WorkEngine()
        {
            this.bgw.WorkerReportsProgress = true;
            this.bgw.DoWork += new DoWorkEventHandler(this.bgw_DoWork);
            this.bgw.ProgressChanged += new ProgressChangedEventHandler(this.bgw_ProgressChanged);
        }

        private void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            WorkParam executeParam = null;
            bool flag = false;
            lock (this.list)
            {
                foreach (WorkParam current in this.list)
                {
                    if (current.ID == e.ProgressPercentage)
                    {
                        executeParam = current;
                        flag = true;
                        break;
                    }
                }
            }
            if (flag)
            {
                if (executeParam.OnShowResult != null)
                {
                    executeParam.OnShowResult(e);
                }
            }
        }

        private void bgw_DoWork(object sender, DoWorkEventArgs e)
        {
            bool flag = false;
            WorkParam executeParam = null;
            while (this.running)
            {
                flag = false;
                lock (this.list)
                {
                    for (int i = 0; i < this.list.Count; i++)
                    {
                        if (Math.Abs(this.list[i].LastExecuteDateTime.Subtract(DateTime.Now).TotalSeconds) >= (double)this.list[i].Delay)
                        {
                            executeParam = this.list[i];
                            flag = true;
                            break;
                        }
                    }
                }
                if (flag)
                {
                    if (executeParam.OnHandler != null)
                    {
                        executeParam.OnHandler(executeParam);
                    }
                    //ShowData(executeParam.ID, executeParam.Obj);
                    executeParam.LastExecuteDateTime = DateTime.Now;
                }
                Thread.Sleep(500);
            }
        }

        public void Start()
        {
            this.running = true;
            if (!bgw.IsBusy)
            {
                this.bgw.RunWorkerAsync();
            }
        }

        public void Stop()
        {
            this.running = false;
        }

        public void ShowData(int ID, object o)
        {
            this.bgw.ReportProgress(ID, o);
        }
    }
}
